// Lightweight API client with localStorage fallback.
// In production, set window.APP_CONFIG = { apiBase: 'https://your.api' } to enable real requests.

const cfg = (typeof window !== 'undefined' && window.APP_CONFIG) ? window.APP_CONFIG : {};

async function request(path, { method = 'GET', body, headers = {} } = {}) {
  const base = cfg.apiBase;
  if (!base) return null; // no remote configured
  try {
    const resp = await fetch(`${base.replace(/\/$/, '')}/${path.replace(/^\//, '')}`, {
      method,
      headers: { 'Content-Type': 'application/json', ...headers },
      body: body ? JSON.stringify(body) : undefined,
      credentials: 'include',
    });
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    // Allow empty responses
    const text = await resp.text();
    return text ? JSON.parse(text) : null;
  } catch (e) {
    console.warn('API request failed, falling back to localStorage:', method, path, e.message);
    return null;
  }
}

function lsGet(key, fallback) {
  try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : (fallback ?? null); } catch { return fallback ?? null; }
}
function lsSet(key, value) {
  try { localStorage.setItem(key, JSON.stringify(value)); } catch { }
}

export const api = {
  // Tuning knobs for lightweight eviction
  _limits: {
    maxMessagesPerThread: 200,   // keep last N messages per thread/group
    maxRemoteItins: 50,          // keep last K remote itinerary snapshots
  },
  // Itineraries
  async getItineraries() {
    const remote = await request('/itineraries', { method: 'GET' });
    const list = remote ?? lsGet('itinerariesV2', []);
    // Defensive: filter out items that explicitly belong to other users if backend misconfiguration occurs
    try {
      const myId = await api.getCurrentUserId();
      if (!myId) return list;
      const filtered = Array.isArray(list) ? list.filter(it => !it || typeof it !== 'object' || !it.userId || String(it.userId) === String(myId)) : list;
      return filtered;
    } catch { return list; }
  },

  // AI itinerary generate
  async aiGenerate({ query, days, preferences } = {}) {
    const remote = await request('/ai/itinerary/generate', { method: 'POST', body: { query, days, preferences } });
    return remote; // null when no remote configured
  },
  async setItineraries(list) {
    // Tag items with current userId (if available) for extra safety
    let payload = list;
    try {
      const myId = await api.getCurrentUserId();
      if (myId) {
        payload = (Array.isArray(list) ? list : []).map(it => ({ ...(it || {}), userId: myId }));
      }
    } catch { }
    const remote = await request('/itineraries', { method: 'PUT', body: payload });
    if (remote === null) lsSet('itinerariesV2', list);
  },

  // Chats (direct)
  async getChats() {
    const remote = await request('/chats', { method: 'GET' });
    return remote ?? null;
  },
  async setChats(data) {
    const remote = await request('/chats', { method: 'PUT', body: data });
    return remote !== null;
  },

  // Group chats
  async getGroupChats() {
    const remote = await request('/groupChats', { method: 'GET' });
    return remote ?? null;
  },
  async setGroupChats(data) {
    const remote = await request('/groupChats', { method: 'PUT', body: data });
    return remote !== null;
  },

  // Companions
  async getCompanions() {
    const remote = await request('/companions', { method: 'GET' });
    return Array.isArray(remote) ? remote : [];
  },
  async setCompanions(list) {
    const remote = await request('/companions', { method: 'PUT', body: list });
    return remote !== null;
  },
  // Companion Invites
  async listCompanionInvites() {
    const remote = await request('/companions/invites', { method: 'GET' });
    return Array.isArray(remote) ? remote : [];
  },
  async createCompanionInvite({ phone }) {
    const resp = await request('/companions/invites', { method: 'POST', body: { phone } });
    return resp; // { ok, inviteId, status, duplicate? } or null
  },
  async acceptCompanionInvite(inviteId) {
    const resp = await request(`/companions/invites/${inviteId}/accept`, { method: 'POST' });
    return resp; // { ok, status }
  },
  async declineCompanionInvite(inviteId) {
    const resp = await request(`/companions/invites/${inviteId}/decline`, { method: 'POST' });
    return resp; // { ok, status }
  },

  // Groups
  async getGroups() {
    const remote = await request('/groups', { method: 'GET' });
    return Array.isArray(remote) ? remote : [];
  },
  async setGroups(list) {
    const remote = await request('/groups', { method: 'PUT', body: list });
    return remote !== null;
  },

  // Users
  async getUsers() {
    const remote = await request('/users', { method: 'GET' });
    return remote ?? lsGet('usersV1', []);
  },
  async setUsers(list) {
    const remote = await request('/users', { method: 'PUT', body: list });
    if (remote === null) lsSet('usersV1', list);
  },
  async getCurrentUserId() {
    const remote = await request('/auth/session', { method: 'GET' });
    return remote?.userId ?? lsGet('currentUserId', null);
  },
  async setCurrentUserId(id) {
    const remote = await request('/auth/session', { method: 'PUT', body: { userId: id } });
    if (remote === null) lsSet('currentUserId', id);
  },

  // Auth
  async login({ phone, password }) {
    const resp = await request('/auth/login', { method: 'POST', body: { phone, password } });
    return resp; // { ok, userId, user } or null if no backend
  },
  async logout() {
    const resp = await request('/auth/logout', { method: 'POST' });
    return resp; // { ok } or null
  },
  async register({ phone, password, nickname }) {
    const resp = await request('/auth/register', { method: 'POST', body: { phone, password, nickname } });
    return resp; // { ok, userId, user } or null
  },

  // Chat Remote Itinerary snapshots (simulate "server copies")
  async getChatRemoteItineraries() {
    const remote = await request('/chatRemoteItineraries', { method: 'GET' });
    return remote ?? null;
  },
  async setChatRemoteItineraries(data) {
    const remote = await request('/chatRemoteItineraries', { method: 'PUT', body: data });
    return remote !== null;
  },

  // Chat itinerary collapse state (UI local only)
  async getChatItineraryCollapse() {
    return lsGet('chatItineraryCollapseV1', {});
  },
  async setChatItineraryCollapse(data) {
    lsSet('chatItineraryCollapseV1', data);
  },

  // Feedback
  async submitFeedback({ text, meta } = {}) {
    const ok = await request('/feedback', { method: 'POST', body: { text, meta } });
    if (ok) return ok;
    // Fallback to localStorage list
    const MAX_LS = 200; // cap local cache
    const arr = lsGet('feedbacksV1', []) || [];
    arr.push({ ts: Date.now(), text: String(text || ''), meta: meta || {} });
    const trimmed = arr.slice(-MAX_LS);
    lsSet('feedbacksV1', trimmed);
    return { ok: true, local: true };
  },
};

export default api;
